﻿using System;
using Microsoft.Xna.Framework;

namespace Epitech.Krisk.Kinect.Sensor.Gestures.Swipes
{

    public class SwipeGestureDetector : GestureDetector
    {
        private DateTime _lastGestureDate = DateTime.Now;
        protected const float SwipeMinimalLengthV = 0.4f;
        protected const float SwipeMinimalLengthH = 0.2f;
        protected const float SwipeMaximalHeight = 0.4f;
        protected const int SwipeMininalDuration = 250;
        protected const int SwipeMaximalDuration = 400;


        /// <summary>
        /// When a swipe to the left is detected
        /// </summary>
        public event EventHandler OnSwipeToLeft;

        /// <summary>
        /// When a swipe to the right is detected
        /// </summary>
        public event EventHandler OnSwipeToRight;

        /// <summary>
        /// When a swipe to the right is detected
        /// </summary>

        public event EventHandler OnSwipeToTop;
        /// <summary>
        /// When a swipe to the right is detected
        /// </summary>
        public event EventHandler OnSwipeToBottom;

        protected SwipeGestureDetector(int numberOfGestureAnalyzed = 20, int minimalPeriodBetweenGesture = 0)
            : base(numberOfGestureAnalyzed, minimalPeriodBetweenGesture)
        {
        }

        protected bool ScanPositions(Func<Vector3, Vector3, bool> heightFunction,
                                     Func<Vector3, Vector3, bool> directionFunction,
                                     Func<Vector3, Vector3, bool> lengthFunction, int minTime, int maxTime)
        {
            int start = 0;

            for (int index = 1; index < Entries.Count - 1; index++)
            {
                if (!heightFunction(Entries[0].Position, Entries[index].Position) ||
                    !directionFunction(Entries[index].Position, Entries[index + 1].Position))
                {
                    start = index;
                }

                if (lengthFunction(Entries[index].Position, Entries[start].Position))
                {
                    double totalMilliseconds = (Entries[index].Time - Entries[start].Time).TotalMilliseconds;
                    if (totalMilliseconds >= minTime && totalMilliseconds <= maxTime)
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        // if a gesture is detected then raise the corresponding event
        protected void RaiseGestureDetected(GestureType gesture)
        {
            if (DateTime.Now.Subtract(_lastGestureDate).TotalMilliseconds > MinimalPeriodBetweenGesture)
            {
                switch (gesture)
                {
                    case GestureType.SwipeToleft:
                        RaiseSwipeToLeftEvent();
                        break;
                    case GestureType.SwipeToRight:
                        RaiseSwipeToRightEvent();
                        break;
                        case GestureType.SwipeToBottom:
                        RaiseSwipeToBottomEvent();
                        break;
                        case GestureType.SwipeToTop:
                        RaiseSwipeToTopEvent();
                        break;
                }
                _lastGestureDate = DateTime.Now;
            }

            Entries.Clear();
        }

        private void RaiseSwipeToTopEvent()
        {
            EventHandler handler = OnSwipeToTop;
            if (handler != null)
                handler(this, EventArgs.Empty);
        }

        private void RaiseSwipeToBottomEvent()
        {
            EventHandler handler = OnSwipeToBottom;
            if (handler != null)
                handler(this, EventArgs.Empty);

        }

        protected virtual void RaiseSwipeToRightEvent()
        {
            EventHandler handler = OnSwipeToRight;
            if (handler != null)
                handler(this, EventArgs.Empty);
        }

        protected virtual void RaiseSwipeToLeftEvent()
        {
            EventHandler handler = OnSwipeToLeft;
            if (handler != null)
                handler(this, EventArgs.Empty);
        }

        protected override void LookForGesture()
        {
        }
    }

}